﻿#region Header

/*
Behavioral Rating of Dancing Human Crowds based on Motion Patterns
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfeller
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System;
using System.IO;
using DexterLib;
using Microsoft.VisualStudio.TestTools.UnitTesting;

#endregion

namespace Tests.Basics {
	/// <summary>
	/// <see cref="http://69.10.233.10/KB/directx/picturesfrommovie.aspx"/>
	/// Pressing the "Print Screen" key while playing a movie file in Windows Media Player will not allow you to save the current frame. 
	/// So I started to look for a simple way to grab a frame from movie files playing in the most common media applications 
	/// (e.g., Windows Media Player, QuickTime, or DivX Player).
	///  It turned out to be more complicated than I originally thought.
	///  Hence, I decided to write up a sample application and submit it to CodeProject since I have used their resources quite often;
	///  it was a way to thank the people behind this site.
	/// Microsoft approach to this problem would be using DirectShow but there is no managed equivalent of it. 
	/// By digging in the DirectX documentation, I discovered the MediaDet class that is used in some VB samples. 
	/// It is not the ideal solution but it is good enough for many situations. 
	/// By wrapping the qedit.dll from the DirectShow Developer Runtime (which is included in the Extras of the DirectX SDK) in a managed assembly,
	///  I could make calls to MediaDetClass::WriteBitmapBits method that saves a frame from a movie file to a bitmap file.
	/// </summary>
	[TestClass]
	public class TestVideoGraber {
		#region Test Methods

		[TestMethod]
		[DeploymentItem("Videos\\Sample.wmv", "Videos")]
		public void TestGrabVideoFrames() {
			// create grabber
			var mediaDetClass = new MediaDetClass();
			// asign video file
			mediaDetClass.Filename = "Videos\\Sample.wmv";
			mediaDetClass.CurrentStream = 0;

			var length = (int)mediaDetClass.StreamLength;
			string prefix = Guid.NewGuid() + "_";
			for (double i = 0; i < length; i += 1.0 / 24.0) {
				// grabe file at position x with a given resolution
				mediaDetClass.WriteBitmapBits(i, 208, 160, prefix + i + ".jpg");
			}
			// images from the video are in the test folder
			// remarks, not all videos are grabable :( (wmf files works)
		}

		[TestMethod]
		public void TestGrabVideoMaterialsMiddle() {
			// create grabber
			var mediaDetClass = new MediaDetClass();
			// asign video file
			mediaDetClass.Filename = Directory.GetCurrentDirectory() + @"\..\..\..\..\..\..\099_Materials\Middle\Sample.wmv";
			mediaDetClass.CurrentStream = 0;
			double frameRate = 10.0;
			var length = (int)mediaDetClass.StreamLength;
			string prefix = Directory.GetCurrentDirectory() + @"\..\..\..\..\..\..\099_Materials\Middle\Sample_";
			int index = 0;
			for (double i = 0; i < length; i += 1.0 / frameRate) {
				// grabe file at position x with a given resolution
				mediaDetClass.WriteBitmapBits(i, 720, 576, prefix + (index++).ToString("00000") + ".jpg");
			}
			// images from the video are in the test folder
			// remarks, not all videos are grabable :( (wmf files works)
		}

		[TestMethod]
		public void TestGrabVideoMaterialsBigCityBeatsSummerClub() {
			// create grabber
			var mediaDetClass = new MediaDetClass();
			// asign video file
			mediaDetClass.Filename = Directory.GetCurrentDirectory() +
									 @"\..\..\..\..\..\..\099_Materials\Middle\Big City Beats Summer Club.wmv";
			mediaDetClass.CurrentStream = 0;
			double frameRate = 10.0;
			var length = (int)mediaDetClass.StreamLength;
			string prefix = Directory.GetCurrentDirectory() +
							@"\..\..\..\..\..\..\099_Materials\Middle\Big City Beats Summer Club_";
			int index = 0;
			for (double i = 0; i < length; i += 1.0 / frameRate) {
				// grabe file at position x with a given resolution
				mediaDetClass.WriteBitmapBits(i, 320, 240, prefix + (index++).ToString("00000") + ".jpg");
			}
			// images from the video are in the test folder
			// remarks, not all videos are grabable :( (wmf files works)
		}

		[TestMethod]
		public void TestGrabVideoMaterialsBigCityBeatsSummerClubNotHappyToHappy() {
			// create grabber
			var mediaDetClass = new MediaDetClass {
				Filename =
					(Directory.GetCurrentDirectory() +
					 @"\..\..\..\..\..\..\099_Materials\Middle\BadToGoodEmotionBigCityBeatsSummerClub.wmv"),
				CurrentStream = 0
			};
			// asign video file
			double frameRate = 25.0;
			var length = (int)mediaDetClass.StreamLength;
			string prefix = Directory.GetCurrentDirectory() +
							@"\..\..\..\..\..\..\099_Materials\Middle\NotHappyToHappy\Big City Beats Summer Club_";
			int index = 0;
			for (double i = 0; i < length; i += 1.0 / frameRate) {
				// grabe file at position x with a given resolution
				mediaDetClass.WriteBitmapBits(i, 320, 240, prefix + (index++).ToString("00000") + ".jpg");
			}
			// images from the video are in the test folder
			// remarks, not all videos are grabable :( (wmf files works)
		}

		[TestMethod]
		public void TestVideo1() {
			// create grabber
			var mediaDetClass = new MediaDetClass {
				Filename =
					(Directory.GetCurrentDirectory() +
					 @"\..\..\..\..\..\..\099_Materials\Middle\Video1.wmv"),
				CurrentStream = 0
			};
			// asign video file
			double frameRate = 30.0;
			var length = (int)mediaDetClass.StreamLength;
			string prefix = Directory.GetCurrentDirectory() +
							@"\..\..\..\..\..\..\099_Materials\Middle\Video1\Video1";
			int index = 0;
			for (double i = 0; i < length; i += 1.0 / frameRate) {
				// grabe file at position x with a given resolution
				mediaDetClass.WriteBitmapBits(i, 320, 240, prefix + (index++).ToString("00000") + ".jpg");
			}
			// images from the video are in the test folder
			// remarks, not all videos are grabable :( (wmf files works)
		}

		[TestMethod]
		public void TestVideo2() {
			// create grabber
			var mediaDetClass = new MediaDetClass {
				Filename =
					(Directory.GetCurrentDirectory() +
					 @"\..\..\..\..\..\..\099_Materials\Middle\Video2.wmv"),
				CurrentStream = 0
			};
			// asign video file
			double frameRate = 30.0;
			var length = (int)mediaDetClass.StreamLength;
			string prefix = Directory.GetCurrentDirectory() +
							@"\..\..\..\..\..\..\099_Materials\Middle\Video2\Video2";
			int index = 0;
			for (double i = 0; i < length; i += 1.0 / frameRate) {
				// grabe file at position x with a given resolution
				mediaDetClass.WriteBitmapBits(i, 320, 240, prefix + (index++).ToString("00000") + ".jpg");
			}
			// images from the video are in the test folder
			// remarks, not all videos are grabable :( (wmf files works)
		}

		[TestMethod]
		public void TestVideo3() {
			GrapFrames("Video3");
		}

		[TestMethod]
		public void TestVideo4() {
			GrapFrames("Video4");
		}

		[TestMethod]
		public void TestVideo5() {
			GrapFrames("Video6");
		}

		[TestMethod]
		public void TestVideo6() {
			GrapFrames("Video6");
		}

		[TestMethod]
		public void TestVideo7() {
			GrapFrames("Video7");
		}

		[TestMethod]
		public void TestVideo10() {
			var videoFileName = "video10";
			// create grabber
			var mediaDetClass = new MediaDetClass {
				Filename =
					(Directory.GetCurrentDirectory() + @"\..\..\..\..\..\..\099_Materials\Middle\" + videoFileName +
					 ".mp4"),
				CurrentStream = 0
			};
			// asign video file
			double frameRate = 25.0;
			var length = (int)mediaDetClass.StreamLength;
			string prefix = Directory.GetCurrentDirectory() + @"\..\..\..\..\..\..\099_Materials\Middle\" + videoFileName + "\\" +
							videoFileName;
			int index = 0;
			for (double i = 0; i < length; i += 1.0 / frameRate) {
				// grabe file at position x with a given resolution
				mediaDetClass.WriteBitmapBits(i, 424, 240, prefix + (index++).ToString("00000") + ".jpg");
			}
		}


		private void GrapFrames(string videoFileName) {
			// create grabber
			var mediaDetClass = new MediaDetClass {
				Filename =
					(Directory.GetCurrentDirectory() +
					 @"\..\..\..\..\..\..\099_Materials\Middle\" + videoFileName + ".wmv"),
				CurrentStream = 0
			};
			// asign video file
			double frameRate = 25.0;
			var length = (int)mediaDetClass.StreamLength;
			string prefix = Directory.GetCurrentDirectory() +
							@"\..\..\..\..\..\..\099_Materials\Middle\" + videoFileName + "\\" + videoFileName;
			int index = 0;
			for (double i = 0; i < length; i += 1.0 / frameRate) {
				// grabe file at position x with a given resolution
				mediaDetClass.WriteBitmapBits(i, 320, 240, prefix + (index++).ToString("00000") + ".jpg");
			}
		}

		#endregion
	}
}